"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = require("axios");
const CryptoJs = require("crypto-js");

const pageSize = 25;
const userAgent = "MusicFree/Plugin-Navidrome";
const ALL_SONGS_TAG = { id: 'navidrome__all_songs', title: '所有歌曲' };

// 获取用户配置
function getUserVariables() {
    return (env?.getUserVariables && env.getUserVariables()) || {};
}

// 标准化URL
function normalizeUrl(url) {
    if (!url) return null;
    if (!url.startsWith("http://") && !url.startsWith("https://")) {
        url = `http://${url}`;
    }
    return url.replace(/\/+$/, "");
}

// 获取认证参数
function getAuthParams() {
    const { username, password } = getUserVariables();
    if (!username || !password) {
        throw new Error("未配置用户名或密码");
    }
    
    const salt = Math.random().toString(16).slice(2);
    const token = CryptoJs.MD5(`${password}${salt}`).toString(CryptoJs.enc.Hex);
    return { u: username, s: salt, t: token, c: "MusicFree", v: "1.16.1", f: "json" };
}

// HTTP请求封装 (Subsonic API)
async function httpGet(urlPath, params = {}) {
    const { url } = getUserVariables();
    const normalizedUrl = normalizeUrl(url);
    if (!normalizedUrl) {
        throw new Error("未配置服务器地址");
    }
    
    const authParams = getAuthParams();
    const fullUrl = `${normalizedUrl}/rest/${urlPath}`;
    
    try {
        const response = await axios_1.default.get(fullUrl, {
            params: { ...authParams, ...params },
            timeout: 10000,
            headers: { 'User-Agent': userAgent }
        });
        
        const responseData = response.data?.['subsonic-response'];
        if (responseData?.status === 'failed') {
            throw new Error(`Navidrome API错误: ${responseData.error?.message || '未知错误'}`);
        }
        
        return responseData;
    } catch (error) {
        if (error.response?.status === 401) {
            throw new Error("认证失败，请检查用户名和密码");
        }
        throw new Error(`无法连接到Navidrome服务器: ${error.message}`);
    }
}

// Native API请求封装
let nativeTokenCache = { token: null, time: 0 };

async function getNativeToken() {
    const { url, username, password } = getUserVariables();
    const normalizedUrl = normalizeUrl(url);
    if (!normalizedUrl || !username || !password) {
        return null;
    }
    
    const now = Date.now();
    // 使用缓存token（5分钟内有效）
    if (nativeTokenCache.token && now - nativeTokenCache.time < 5 * 60 * 1000) {
        return nativeTokenCache.token;
    }
    
    try {
        const response = await axios_1.default.post(`${normalizedUrl}/auth/login`, 
            { username, password }, 
            {
                headers: { 
                    'Content-Type': 'application/json', 
                    'User-Agent': userAgent 
                }, 
                timeout: 10000
            }
        );
        
        if (response.data?.token) {
            nativeTokenCache = { token: response.data.token, time: now };
            return response.data.token;
        }
        return null;
    } catch (error) {
        console.error("获取Native Token失败:", error.message);
        return null;
    }
}

async function httpGetNative(path, params = {}) {
    const { url } = getUserVariables();
    const normalizedUrl = normalizeUrl(url);
    if (!normalizedUrl) {
        throw new Error("未配置服务器地址");
    }
    
    const nativeToken = await getNativeToken();
    if (!nativeToken) {
        throw new Error("无法获取认证令牌，请检查用户名和密码");
    }
    
    const fullUrl = `${normalizedUrl}/api/${path}`;
    
    try {
        const response = await axios_1.default.get(fullUrl, {
            params,
            headers: {
                'x-nd-authorization': `Bearer ${nativeToken}`,
                'User-Agent': userAgent
            },
            timeout: 10000
        });
        
        if (response.status < 200 || response.status >= 300) {
            throw new Error(`Navidrome Native API请求失败，HTTP状态码: ${response.status}`);
        }
        
        return {
            data: response.data,
            headers: response.headers
        };
    } catch (error) {
        throw new Error(`无法连接到Navidrome Native API: ${error.message}`);
    }
}

// 生成封面URL
function generateCoverArtUrl(coverArtId) {
    if (!coverArtId) return null;
    const { url } = getUserVariables();
    const normalizedUrl = normalizeUrl(url);
    if (!normalizedUrl) return null;
    
    const authParams = getAuthParams();
    const coverUrl = new URL(`${normalizedUrl}/rest/getCoverArt`);
    Object.entries(authParams).forEach(([key, value]) => coverUrl.searchParams.append(key, value));
    coverUrl.searchParams.append('id', String(coverArtId));
    return coverUrl.toString();
}

// 格式化音乐项目
function formatMusicItem(song) {
    return {
        id: String(song.id),
        title: song.title || "未知歌曲",
        artist: song.artist || "未知艺术家",
        album: song.album || "未知专辑",
        artwork: generateCoverArtUrl(song.coverArt || song.albumId),
        duration: song.duration || 0,
        lyrics: song.lyrics || null,
        _source: 'navidrome'
    };
}

// 格式化专辑项目
function formatAlbumItem(album) {
    return {
        id: String(album.id),
        title: album.name || album.title || "未知专辑",
        artist: album.artist || "未知艺术家",
        artwork: generateCoverArtUrl(album.coverArt || album.id),
        description: `歌曲数: ${album.songCount || '?'}`,
        songCount: album.songCount
    };
}

// 格式化艺术家项目
function formatArtistItem(artist) {
    return {
        id: String(artist.id),
        name: artist.name || "未知艺术家",
        avatar: generateCoverArtUrl(artist.id ? `ar-${artist.id}` : null),
        platform: 'navidrome'
    };
}

// 格式化歌单项目
function formatSheetItem(playlist, username = "Navidrome用户") {
    const id = String(playlist.id);
    const title = playlist.name || "未知播放列表";
    const owner = playlist.ownerName || playlist.owner || username;
    const artwork = generateCoverArtUrl(id ? `pl-${id}` : null);
    const songCount = playlist.songCount || 0;
    const duration = playlist.duration || 0;
    const description = `歌曲: ${songCount}, 时长: ${Math.round(duration / 60)}分钟`;
    
    return { 
        id, 
        title, 
        artist: owner, 
        artwork, 
        description, 
        songCount
    };
}

// 将结构化歌词转换为LRC格式
function formatStructuredLyricsToLrc(lyricsData) {
    if (!lyricsData || !Array.isArray(lyricsData) || lyricsData.length === 0) {
        return null;
    }
    
    // 查找同步歌词（synced: true）
    const syncedLyrics = lyricsData.find(l => l.synced === true && Array.isArray(l.line));
    if (!syncedLyrics) {
        return null;
    }
    
    let lrcText = '';
    
    // 处理每一行歌词
    for (const line of syncedLyrics.line) {
        if (typeof line.start === 'number' && typeof line.value === 'string') {
            // 将毫秒转换为LRC时间格式 [mm:ss.xx]
            const totalSeconds = Math.floor(line.start / 1000);
            const minutes = Math.floor(totalSeconds / 60);
            const seconds = totalSeconds % 60;
            const milliseconds = Math.floor((line.start % 1000) / 10);
            
            const timeStr = `[${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}.${String(milliseconds).padStart(2, '0')}]`;
            lrcText += `${timeStr}${line.value}\n`;
        }
    }
    
    return lrcText.trim() || null;
}

// 搜索音乐
async function searchMusic(query, page) {
    const start = (page - 1) * pageSize;
    const end = start + pageSize;
    
    const response = await httpGetNative('song', {
        title: query,
        _start: start,
        _end: end
    });
    
    const songs = response.data || [];
    const total = parseInt(response.headers['x-total-count'] || '0', 10);
    const isEnd = (start + songs.length) >= total;
    
    return {
        isEnd,
        data: songs.map(formatMusicItem)
    };
}

// 搜索专辑
async function searchAlbum(query, page) {
    const start = (page - 1) * pageSize;
    const end = start + pageSize;
    
    const response = await httpGetNative('album', {
        name: query,
        _start: start,
        _end: end
    });
    
    const albums = response.data || [];
    const total = parseInt(response.headers['x-total-count'] || '0', 10);
    const isEnd = (start + albums.length) >= total;
    
    return {
        isEnd,
        data: albums.map(formatAlbumItem)
    };
}

// 搜索艺术家
async function searchArtist(query, page) {
    const start = (page - 1) * pageSize;
    const end = start + pageSize;
    
    const response = await httpGetNative('artist', {
        name: query,
        _start: start,
        _end: end
    });
    
    const artists = response.data || [];
    const total = parseInt(response.headers['x-total-count'] || '0', 10);
    const isEnd = (start + artists.length) >= total;
    
    return {
        isEnd,
        data: artists.map(formatArtistItem)
    };
}

// 搜索歌单
async function searchSheet(query, page) {
    const userVariables = getUserVariables();
    const username = userVariables.username || "Navidrome用户";
    const start = (page - 1) * pageSize;
    const end = start + pageSize;
    
    const params = { 
        _start: start, 
        _end: end, 
        _sort: 'name', 
        _order: 'ASC' 
    };
    
    if (query && query.trim()) {
        params.name = query.trim();
    }
    
    const response = await httpGetNative('playlist', params);
    const playlists = response.data || [];
    const total = parseInt(response.headers['x-total-count'] || '0', 10);
    const isEnd = (start + playlists.length) >= total;
    
    return { 
        isEnd, 
        data: playlists.map(p => formatSheetItem(p, username)) 
    };
}

// 获取专辑详情
async function getAlbumInfo(albumItem) {
    const data = await httpGet('getAlbum', { id: albumItem.id });
    const albumData = data?.album || {};
    const songs = albumData.song || [];
    
    return {
        isEnd: true,
        musicList: songs.map(formatMusicItem),
        albumItem: {
            id: albumItem.id,
            title: albumData.name || albumItem.title,
            artist: albumData.artist,
            artwork: generateCoverArtUrl(albumData.coverArt),
            description: albumData.artist && albumData.year 
                ? `${albumData.artist} - ${albumData.year}` 
                : albumData.artist || "未知专辑信息"
        }
    };
}

// 获取歌单详情
async function getMusicSheetInfo(sheetItem, page) {
    // 如果是"所有歌曲"特殊标签
    if (sheetItem.id === ALL_SONGS_TAG.id) {
        return await getAllSongs(page);
    }
    
    const start = (page - 1) * pageSize;
    const end = start + pageSize;
    
    const response = await httpGetNative(`playlist/${sheetItem.id}/tracks`, { 
        _start: start, 
        _end: end 
    });
    
    const tracks = response.data || [];
    const total = parseInt(response.headers['x-total-count'] || '0', 10);
    const isEnd = (start + tracks.length) >= total;
    
    // 如果是第一页，获取歌单额外信息
    let supplementarySheetData = {};
    if (page === 1) {
        try {
            const userVariables = getUserVariables();
            const username = userVariables.username || "Navidrome用户";
            const playlistInfoResponse = await httpGetNative(`playlist/${sheetItem.id}`, {});
            const playlistData = playlistInfoResponse.data;
            supplementarySheetData = formatSheetItem(playlistData || { id: sheetItem.id, name: sheetItem.title }, username);
            if (playlistData?.comment) {
                supplementarySheetData.description = playlistData.comment;
            }
        } catch (e) {
            supplementarySheetData = { 
                id: sheetItem.id, 
                title: sheetItem.title, 
                artist: username 
            };
        }
    }
    
    return { 
        isEnd, 
        musicList: tracks.map(formatMusicItem), 
        sheetItem: page === 1 ? supplementarySheetData : undefined 
    };
}

// 获取所有歌曲
async function getAllSongs(page) {
    const offset = (page - 1) * pageSize;
    
    try {
        const response = await httpGetNative('song', { 
            _start: offset, 
            _end: offset + pageSize, 
            _sort: 'title', 
            _order: 'ASC' 
        });
        
        const songs = response.data || [];
        const total = parseInt(response.headers['x-total-count'] || '0', 10);
        const isEnd = (offset + songs.length) >= total;
        
        return {
            isEnd,
            musicList: songs.map(formatMusicItem),
            sheetItem: page === 1 ? { 
                id: ALL_SONGS_TAG.id, 
                title: ALL_SONGS_TAG.title, 
                description: "服务器上的全部音乐" 
            } : undefined
        };
    } catch (e) {
        return { isEnd: true, musicList: [] };
    }
}

// 获取艺术家作品
async function getArtistWorks(artistItem, page, type) {
    try {
        if (type === 'music') {
            const start = (page - 1) * pageSize;
            const end = start + pageSize;
            
            const response = await httpGetNative('song', { 
                artist_id: artistItem.id, 
                _start: start, 
                _end: end 
            });
            
            const songs = response.data || [];
            const total = parseInt(response.headers['x-total-count'] || '0', 10);
            const isEnd = (start + songs.length) >= total;
            
            return { 
                isEnd, 
                data: songs.map(formatMusicItem) 
            };
        }
        
        if (type === 'album') {
            if (page > 1) {
                return { isEnd: true, data: [] };
            }
            
            const data = await httpGet('getArtist', { id: artistItem.id });
            const albums = data?.artist?.album || [];
            
            return { 
                isEnd: true, 
                data: albums.map(formatAlbumItem) 
            };
        }
        
        return { isEnd: true, data: [] };
    } catch (error) {
        return { isEnd: true, data: [] };
    }
}

// 获取推荐歌单
async function getRecommendSheetsByTag(tag, page) {
    const userVariables = getUserVariables();
    const username = userVariables.username || "Navidrome用户";
    
    // 如果是空标签，显示所有歌单和特殊标签
    if (tag.id === '') {
        const start = (page - 1) * pageSize;
        const end = start + pageSize;
        
        let playlists = [];
        let isEnd = true;
        
        try {
            const response = await httpGetNative('playlist', { 
                _start: start, 
                _end: end, 
                _sort: 'name', 
                _order: 'ASC' 
            });
            
            playlists = response.data || [];
            const total = parseInt(response.headers['x-total-count'] || '0', 10);
            isEnd = (start + playlists.length) >= total || playlists.length < pageSize;
        } catch (e) {
            console.error("获取播放列表失败:", e.message);
            isEnd = true;
            playlists = [];
        }
        
        let result = playlists.map(p => formatSheetItem(p, username));
        
        // 第一页添加"所有歌曲"特殊标签
        if (page === 1) {
            result.unshift({
                id: ALL_SONGS_TAG.id,
                title: ALL_SONGS_TAG.title,
                artist: username,
                description: "浏览服务器上的所有歌曲"
            });
        }
        
        return { isEnd, data: result };
    }
    
    return { isEnd: true, data: [] };
}

// 获取媒体源
async function getMediaSource(musicItem) {
    const { url } = getUserVariables();
    const normalizedUrl = normalizeUrl(url);
    if (!normalizedUrl) {
        throw new Error("未配置服务器地址");
    }
    
    const authParams = getAuthParams();
    const streamUrl = new URL(`${normalizedUrl}/rest/stream`);
    
    Object.entries(authParams).forEach(([key, value]) => {
        streamUrl.searchParams.append(key, value);
    });
    
    streamUrl.searchParams.append('id', musicItem.id);
    return { url: streamUrl.toString() };
}

// 获取歌词
async function getLyric(musicItem) {
    try {
        // 歌曲已经有歌词字段，直接使用
        if (musicItem.lyrics) {
            // 尝试解析结构化歌词
            const lyrics = JSON.parse(musicItem.lyrics)

            const lrcText = formatStructuredLyricsToLrc(lyrics);
            if (lrcText) {
                return { rawLrc: lrcText };
            }
        }

    } catch (error) {}
    
    return null;
}

module.exports = {
    platform: "Navidrome",
    version: "1.0.0",
    author: 'Hls',
    srcUrl: "https://gitee.com/hs5230/MF_Navidrome/raw/master/Navidrome.js",
    cacheControl: "no-cache",
    
    userVariables: [
        { key: "url", name: "服务器地址" },
        { key: "username", name: "用户名" },
        { key: "password", name: "密码" }
    ],
    
    supportedSearchType: ["music", "album", "sheet", "artist"],
    
    async search(query, page, type) {
        try {
            if (type === "music") {
                return await searchMusic(query, page);
            }
            if (type === "album") {
                return await searchAlbum(query, page);
            }
            if (type === "artist") {
                return await searchArtist(query, page);
            }
            if (type === "sheet") {
                return await searchSheet(query, page);
            }
            return { isEnd: true, data: [] };
        } catch (error) {
            return { isEnd: true, data: [] };
        }
    },
    
    async getAlbumInfo(albumItem) {
        try {
            return await getAlbumInfo(albumItem);
        } catch (error) {
            return { isEnd: true, musicList: [] };
        }
    },
    
    async getMusicSheetInfo(sheetItem, page) {
        try {
            return await getMusicSheetInfo(sheetItem, page);
        } catch (error) {
            return { isEnd: true, musicList: [] };
        }
    },
    
    async getArtistWorks(artistItem, page, type) {
        try {
            return await getArtistWorks(artistItem, page, type);
        } catch (error) {
            return { isEnd: true, data: [] };
        }
    },
    
    async getRecommendSheetsByTag(tag, page) {
        try {
            return await getRecommendSheetsByTag(tag, page);
        } catch (error) {
            return { isEnd: true, data: [] };
        }
    },
    
    async getMediaSource(musicItem) {
        try {
            return await getMediaSource(musicItem);
        } catch (error) {
            return null;
        }
    },
    
    async getLyric(musicItem) {
        try {
            return await getLyric(musicItem);
        } catch (error) {
            return null;
        }
    }
};